/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.typhosoft.jcommon.observer;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author SantonocitoM
 */
public class NotifierThread extends Thread {

    private List<Object> notifications;
    private IClient consumer;
    private NotifierExecutor executor;
    private Semaphore s = new Semaphore(0);
    private final Object lock = new Object();

    private NotifierThread() {
    }

    NotifierThread(NotifierExecutor executor, int idx) {
        super("MY-Thread-" + idx);
        this.executor = executor;
    }

    public boolean isFree() {
        boolean free;
        synchronized (lock) {
            free = (consumer == null);
        }
        return free;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof NotifierThread) {
            NotifierThread other = (NotifierThread) obj;
            return this.consumer == other.consumer;
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 47 * hash + Objects.hashCode(this.consumer);
        return hash;
    }

    public void addJob(IClient consumer, List<Object> notifications) {
        //TraceLogger.info(this, "addJob  " + consumer);
        synchronized (lock) {
            this.consumer = consumer;
            this.notifications = notifications;
        }
        if (this.consumer != null && this.notifications != null) {
            s.release();
        }

    }

    public IClient getConsumer() {
        return consumer;
    }

    @Override
    public void run() {
        while (true) {
            //TraceLogger.info(this, super.getName() + " wait to acquire");
            try {
                s.acquire();
            } catch (InterruptedException ex) {
            }

            try {
                //TraceLogger.info(this, super.getName() + " CALL consumer " + consumer.getClass().getName() + " " + notifications.size() + " events");
                consumer.receiveNotification(notifications);
                //TraceLogger.info(this, super.getName() + " END consumer " + consumer.getClass().getName() + " " + notifications.size() + " events");
            } catch (Exception ex) {
                Logger.getLogger(this.getName()).log(Level.SEVERE, null, ex);
            } finally {

                synchronized (lock) {
                    consumer = null;
                    notifications = null;

                }
                //TraceLogger.info(this, super.getName() + " call endJob");
                executor.endJob(this);
            }
        }
    }
}
